package com.gwtjs.dao;

import java.util.List;

import org.hibernate.LockMode;

import com.gwtjs.model.Pager;
import com.gwtjs.model.QueryCondition;

/**
 * <h2 style="color:#F00;font-size:18px;font-weight:bold;">泛型</h2>
 * <p>缺少执行SQL的方法<p>
 * @author aGuang
 *
 * @param <T>
 * @param <PK>
 */
public interface GenericDao<T,PK> {

	public void flush();

	/**
	 * 强制立即清除缓冲（否则仅在事务提交时才更新）
	 */
	public void clear();
	
	/**
	 * 加锁指定的实体
	 * @param entity
	 * @param lockMode
	 */
	public void lock(T entity, LockMode lockMode);
    

	/* ------------------------------------------------------------------- */

	/**
	 * 取实体最大的ＩＤ值
	 * @param entity
	 * @return
	 */
	public Integer getMaxObjectId(final Class<T> entity);
	/**
	 * 新增或修改
	 * 
	 * @param e
	 */
	public void saveOrUpdate(T e) ;

	/**
	 * 新增一个对象
	 * @param e
	 */
	public void save(T e) ;

	/**
	 * 修改一个对象
	 * @param e
	 */
	public void update(T e) ;
	
	/**
	 * 修改对象
	 * @param e
	 */
	public void merge(T e);

	/**
	 * 批量保存
	 * 
	 * @param list
	 */
	public void saveBulk(List<T> list) ;

	/**
	 * 批量更新
	 * 
	 * @param list
	 */
	public void updateBulk(List<T> list) ;

	/**
	 * 按条件删除多个对象
	 * @param entityClass
	 * @param att
	 * @param val
	 */
	public void attrDeletes(Class<T> entityClass,Object att,Object... val);
	/**
	 * 批量删除 ? 待续
	 * 
	 * @param list
	 */
	public void deleteBulk(List<T> list) ;

	/**
	 * 按标识删除一个对象
	 * @param entityClass
	 * @param id
	 */
	public void delete(Class<T> entityClass,PK id);

	/**
	 * 删除一个实体
	 * @param e
	 */
	public void deleteObject(T e) ;

	/**
	 * 推荐使用 {@link deleteBulk}
	 */
	public void deletes(T e);
	
	
	/**
	 * 按标识取一个对象
	 * @param entityClass
	 * @param id
	 * @return
	 */
	public T get(Class<T> entityClass,PK id);
	
	// 根据主键获取实体并加锁。如果没有相应的实体，返回 null。
    @Deprecated
	public T getWithLock(Class<T> entityClass,PK id, LockMode lock);

	/**
	 * 根据查询条件返回唯一一条 记录
	 * 
	 * @return 一个实体
	 */
	public T get(final Class<T> entityClass,
			final String propertyName, final Object value);

	/**
	 * 某标识的对象是否存在
	 * 
	 * @param id
	 * @return
	 */
	public boolean exists(Class<T> entityClass,PK id) ;

	/**
	 * 按标识修改一个属性的值
	 * 
	 * @param attr
	 * @param val
	 * @param entity
	 * @param id
	 */
	public void updateAttr(Class<T> entityClass,String attr, Object val, PK id) ;

	/**
	 * <h2>返回总记录数</h2>
	 * <p>
	 * <h3 style="color:#F00">注意：</h3>
	 * 请在排序和分页前提交sql语句,并且WHERE需要大写
	 * </p>
	 * @deprecated 此方法暂时没有其它的方法调用
	 * @param sql
	 * @return
	 */
	public int getEntityCount(String sql) ;
	
	/**
     * <h2>根据属性值查询单个对象</h2>
     * 
     * @param entityClass
     *            实体类名
     * @param propertyName
     *            属性名
     * @param value
     *            属性值
     * @return 实体对象
     */
	public T findUniqueByProperty(final Class<T> entityClass,
            final String propertyName, final Object value);
	
	/**
     * <h2>根据属性值查询实体是否存在</h2>
     * 
     * @param entityClass
     *            实体类名
     * @param propertyName
     *            参照的属性名
     * @param value
     *            属性值
     * @return 存在则返回true,不存在则返回false
     */
    public boolean isPropertyExist(final Class<T> entityClass,
            final String propertyName, final Object value);

	/*
	 * ------------------------------------ 列表查询
	 * --------------------------------------
	 */

	public Pager<T> findAll(Class<T> entityClass) ;

	public Pager<T> findAll(Class<T> entityClass, String ascProperty, boolean isAsc, int firstResult,
			int maxResult) ;
	
	public Pager<T> findAll(Class<T> entityClass, String ascProperty, boolean isAsc, int firstResult,
			int maxResult ,List<QueryCondition> entities) ;

	/*
	 * --------------------------------\ 模糊查询 /--------------------------------/
	 */
	public Pager<T> findLikeAll(Class<T> entityClass, String ascProperty, boolean isAsc, int firstResult,
			int maxResult ,List<QueryCondition> entities) ;

	/*
	 * --------------------------------\ 其它查询 /--------------------------------/
	 */

	/**
	 * 命名查询的执行
	 */

	/**
	 * 存储过程的执行
	 */
	public Pager<T> namedQuery(Class<T> entityClass,String queryName ,Object val);
}
